package org.changs.nav.ui.nav;


import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.TextureSupportMapFragment;
import com.amap.api.maps.model.LatLng;
import com.amap.api.navi.model.AMapNaviPath;
import com.amap.api.navi.model.NaviLatLng;

import org.changs.aplug.plug.InjectEventBusOnResume;
import org.changs.nav.R;
import org.changs.nav.databinding.RouteMapFragmentBinding;
import org.changs.nav.delegate.amap.AmapRouteHelper;
import org.changs.nav.delegate.amap.RouteOverlayOpt;
import org.changs.nav.delegate.amap.domain.SimpleLocation;
import org.changs.nav.delegate.global.AmapLocationTask;
import org.changs.nav.event.RouteItemClickEvent;
import org.changs.nav.event.RouteRefreshEvent;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.util.ArrayList;

import javax.inject.Inject;

import timber.log.Timber;

/**
 * Created by yincs on 2017/8/30.
 */

public class MapRouteFragment extends BaseMapFragment implements InjectEventBusOnResume {

    private static final String TAG_ROUTE_LIST = "TAG_ROUTE_LIST";
    private static final String TAG_ROUTE_SELECT = "TAG_ROUTE_SELECT";

    public static MapRouteFragment newInstance(int[] ints) {
        Bundle args = new Bundle();
        args.putIntArray(TAG_ROUTE_LIST, ints);
        MapRouteFragment fragment = new MapRouteFragment();
        fragment.setArguments(args);
        return fragment;
    }

    private MyOnMapLoadedListener mOnMapLoadedListener = new MyOnMapLoadedListener();

    private RouteMapFragmentBinding mBinding;
    private AMap mAMap;
    private RouteOverlayOpt mRouteOverlayOpt;
    @Inject AmapLocationTask mAmapLocationTask;


    @Override
    public View setup(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mBinding = DataBindingUtil.inflate(inflater, R.layout.route_map_fragment, container, false);
        initMap();
        initData(savedInstanceState);
        return mBinding.getRoot();
    }

    private void initData(Bundle savedInstanceState) {
        int[] ints;
        int select;
        if (savedInstanceState == null) {
            ints = getArguments().getIntArray(TAG_ROUTE_LIST);
            select = getArguments().getInt(TAG_ROUTE_SELECT, 0);
        } else {
            ints = savedInstanceState.getIntArray(TAG_ROUTE_LIST);
            select = savedInstanceState.getInt(TAG_ROUTE_SELECT, 0);
        }
        showRouteOverlay(ints);
        selectRoute(select);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putIntArray(TAG_ROUTE_LIST, mRouteOverlayOpt.getInts());
        outState.putInt(TAG_ROUTE_SELECT, mRouteOverlayOpt.getSelect());
    }

    private void initMap() {
        if (mAMap == null) {
            mAMap = ((TextureSupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();
        }
        mRouteOverlayOpt = new RouteOverlayOpt(getContext(), mAMap);
        mAMap.setOnMapLoadedListener(mOnMapLoadedListener);
        mAMap.setMapType(4);
        mAMap.getUiSettings().setZoomControlsEnabled(false);

        mBinding.btnZoomIn.setOnClickListener(v ->
                mAMap.animateCamera(CameraUpdateFactory.zoomOut()));
        mBinding.btnZoomOut.setOnClickListener(v ->
                mAMap.animateCamera(CameraUpdateFactory.zoomIn()));
        mBinding.btnRoads.setOnClickListener(v -> {
            mAMap.setTrafficEnabled(!mAMap.isTrafficEnabled());
            mBinding.btnRoads.setImageResource(mAMap.isTrafficEnabled() ?
                    R.mipmap.auto_ic_roads_close : R.mipmap.auto_ic_roads_open);
        });
        mBinding.btnRefresh.setOnClickListener(v -> EventBus.getDefault().post(new RouteRefreshEvent()));
    }

    public void showRouteOverlay(int[] ints) {
        SimpleLocation location = mAmapLocationTask.getLocation();
        if (location == null) {
            onError("定位失败");
            return;
        }

        ArrayList<AMapNaviPath> list = AmapRouteHelper.getAMapNaviPaths(getContext(), ints);
        if (list == null) {
            return;
        }
        mRouteOverlayOpt.clear();
        mRouteOverlayOpt.addRoute(ints, list);
        NaviLatLng endPoint = list.get(0).getEndPoint();


        mOnMapLoadedListener.handle(() ->
                mRouteOverlayOpt.zoomToSpan(new LatLng(location.getLatitude(), location.getLongitude()),
                        new LatLng(endPoint.getLatitude(), endPoint.getLongitude()), mBinding.getRoot()));

        hideLoading();
    }

    public void selectRoute(int position) {
        mRouteOverlayOpt.selectRoute(position);
    }


    @Subscribe
    public void onEvent(RouteItemClickEvent event) {
        if (mRouteOverlayOpt == null) {
            Timber.e("error onEvent: PoiOverlay == null");
            return;
        }
        selectRoute(event.index);
    }

    private class MyOnMapLoadedListener implements AMap.OnMapLoadedListener {

        private boolean isOnMapLoaded;
        private Runnable runnable;

        @Override
        public void onMapLoaded() {
            mAMap.setPointToCenter(mBinding.getRoot().getMeasuredWidth() / 4 * 3, mBinding.getRoot().getMeasuredHeight() / 2);
            isOnMapLoaded = true;
            if (runnable != null)
                runnable.run();
        }

        public void handle(Runnable runnable) {
            if (isOnMapLoaded) {
                runnable.run();
            } else {
                this.runnable = runnable;
            }
        }
    }
}
